<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    /* 
    闭包是什么?    
      - 对象
      - 内部包含了被引用的变量
      - 它被内部函数对象引用着
    产生的条件
      - 函数嵌套
      - 内部函数使用外部函数的局部变量
      - 调用外部函数
    闭包产生的准确时机?
      - 产生内部函数对象时/执行内部函数定义
    闭包作用:
      - 延长了局部变量的生命周期
      - 在函数外部可以反复间接操作局部变量
    闭包的操作
      - 产生闭包: 执行内部函数定义
      - 使用闭包: 调用内部函数
      - 释放闭包: 将指向内部函数的变量赋为null
    闭包的应用
      - IIFE
      - 模块编译后的代码
      - 一些高阶函数:   后面要实现的节流/防抖的工具函数
      - 项目中的例子: 删除品牌


    必须先执行函数定义(函数声明/表达式), 再执行函数
    执行函数定义本质创建函数对象
    */
    (() => {
      let a = 3
      function fn() {
        console.log(++a)
      }
      window.fn3 = fn
    })()
    fn3()
    fn3()


    function fn1() {

      let a = 2
      let b = []
      // const fn2 = function () {
      function fn2 () { // 函数提升
        a++
        console.log(a)
      }

      console.log(fn2)
      return fn2
    }
    const fn = fn1()
    fn()
    fn()
    fn = null
    // 函数名本质: 是指定函数对象的一个变量   它并不是函数对象本身
    // 函数中的局部变量在函数执行完后会自动释放, 除非进入闭包, 且内部函数对象还不是垃圾对象
    // 当fn1执行完, 

  </script>
</body>
</html>